//Copyright (c) 2006-2007 Microsoft Corporation.  All rights reserved
using System;
using System.Globalization;
using System.Xml;

using InvocationFramework.Common;

namespace InvocationFramework.Core
{
    /// <summary>
    /// Esta clase permite ejecutar servicios mediante los adapters configurados (<seealso cref="InvocationFramework.Common.Interfaces.IServiceAdapter"/>)
    /// </summary>
    /// <remarks>
    /// Esta clase es un fachada a todo la infraestructura de Invocation Framework que se utiliza cuando se quiere programar un publicador.
    /// Una descripcion del patron Facade se encuentra en http://www.dofactory.com/Patterns/PatternFacade.aspx
    /// </remarks>
    /// <author>Rodolfo Finochietti 29/11/2005 13.00</author>
    public static class ServicePublisher
    {
        #region Factory

        /// <summary>
        /// Singleton para manejar una sola instancia del broker
        /// </summary>
        private readonly static ServiceBridge _instance;

        /// <summary>
        /// Construtor
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline" )]
        static ServicePublisher( )
        {
            //Creo el singleton del broker
            _instance = new ServiceBridge( );

            //Creo la configuracion que indica que el broker debe cargar solos los adaptadores que son publicables y luego inicializo el broker con esta configuracion
            XmlDocument config = new XmlDocument( );
            config.LoadXml( "<serviceBridge publisherAdapters='true'/>" );
            _instance.Init( "#ServicePublisher#", config );

            //Libero recursos
            config = null;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Permite saber si un servicio esta disponible para ser ejecutado mediante este adaptador
        /// </summary>
        /// <param name="serviceName">Nombre del servicio</param>
        /// <returns>True este adaptador puede ejecutar este servicio, False de lo contrario</returns>
        public static bool IsServiceAvailable( string serviceName )
        {
            return _instance.IsServiceAvailable( serviceName );
        }

        /// <summary>
        /// Verifica si existe una operacion en un servicio
        /// </summary>
        /// <param name="serviceName">Nombre del servicio</param>
        /// <param name="operationName">Nombre de la operacion</param>
        /// <returns>True si la operacion existe en el servicio, de lo contrario False</returns>
        public static bool IsServiceOperationAvailable( string serviceName, string operationName )
        {
            return _instance.IsServiceOperationAvailable( serviceName, operationName );
        }

        /// <summary>
        /// Devuelve una lista con los nombres de los servicios mas utilizados
        /// </summary>
        /// <returns>Una lista con los nombres de los servicios mas utilizados</returns>
        public static string[] GetMostRequestedServices( )
        {
            return _instance.GetMostRequestedServices( );
        }

        /// <summary>
        /// Ejecuta la operacion que se encuentra en un determinado servicio
        /// </summary>
        /// <param name="serviceName">Nombre del servicio</param>
        /// <param name="operationName">Nombre de la operacion a ejecutar</param>
        /// <param name="context">El contexto que se desea propagar junto con al ejecucion del servicios</param>
        /// <param name="parameters">Parametros de la operacion</param>
        /// <returns>Resultado de la ejecucion de la operacion</returns>
        public static object Execute( string serviceName, string operationName, ContextDictionary context, params object[] parameters )
        {
            object result = null;

            //Hay metodos que son propios del service publisher
            if ( serviceName == "ServicePublisher" )
            {
                switch ( operationName )
                {
                    case "IsServiceAvailable":
                        result = IsServiceAvailable( parameters[ 0 ].ToString( ) );
                        break;
                    case "IsServiceOperationAvailable":
                        result = IsServiceOperationAvailable( parameters[ 0 ].ToString( ), parameters[ 1 ].ToString( ) );
                        break;
                    case "GetMostRequestedServices":
                        result = GetMostRequestedServices( );
                        break;
                }
            }
            else
            {
                result = _instance.Execute( serviceName, operationName, context, parameters );
            }

            return result;
        }

        #endregion
    }
}